package com.etong.frame.directive.checker.impl;

import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Value extends CheckerImpl {
	public final static String KEY_FIELD = "field";
	public final static String KEY_VALUE = "value";

	protected Valuer valuer = null;
	protected Comparer comparer = null;
	private String fieldName = "";

	protected Object getField(Object object) {
		@SuppressWarnings("unchecked")
		Map<String, Object> mapObject = (Map<String, Object>) object;
		return mapObject.get(fieldName);
	}

	boolean checkField() {
		return (null != fieldName && !fieldName.isEmpty());
	}

	private interface Valuer {
		boolean equals(Object object);

		int compare(Object object);
	};

	protected class StringValuer implements Valuer {
		String value = "";

		public StringValuer(String value) {
			this.value = value.replace("'", "");
			this.value = this.value.replace("\"", "");
		}

		public boolean equals(Object object) {
			return value.equals(object);
		}

		@Override
		public int compare(Object object) {
			return this.value.compareTo(object.toString());
		}
	};

	protected class NumberValuer implements Valuer {
		Integer value = 0;

		public NumberValuer(String value) {
			this.value = Integer.parseInt(value);
		}

		public boolean equals(Object object) {
			return value.equals(object);
		}

		@Override
		public int compare(Object object) {
			return this.value.toString().compareTo(object.toString());
		}
	};

	protected interface Comparer {
		boolean compare(Object object);
	}

	protected class DefaultComparer implements Comparer {

		@Override
		public boolean compare(Object object) {
			if (!checkField()) {
				return valuer.equals(object);
			} else {
				if (object instanceof Map)
					return valuer.equals(getField(object));
				else
					return false;
			}
		}
	}

	protected class MaxComparer implements Comparer {

		@Override
		public boolean compare(Object object) {
			if (!checkField()) {
				return valuer.compare(object) >= 0;
			} else {
				if (object instanceof Map)
					return valuer.compare(getField(object)) >= 0;
				else
					return false;
			}
		}
	}

	protected class MinComparer implements Comparer {

		@Override
		public boolean compare(Object object) {
			if (!checkField()) {
				return valuer.compare(object) <= 0;
			} else {
				if (object instanceof Map)
					return valuer.compare(getField(object)) <= 0;
				else
					return false;
			}
		}
	}

	public static boolean isNumeric(String str) {
		Pattern pattern = Pattern.compile("[0-9]*");
		return pattern.matcher(str).matches();
	}

	public void setAttribute(String name, String value) {
		if (KEY_FIELD.equalsIgnoreCase(name)) {
			fieldName = value;
			this.fieldName = value.replace("'", "");
			this.fieldName = this.fieldName.replace("\"", "");
		} else if (KEY_VALUE.equalsIgnoreCase(name)) {
			if (!isNumeric(value)) {
				valuer = new StringValuer(value);
			} else {
				valuer = new NumberValuer(value);
			}
		}
	}

	public Value() {
		super("@Value");
	}

	public void clear() {
		this.comparer = null;
		this.valuer = null;
	}

	protected void buildAttribute(String expr) {
		Pattern pattern = Pattern.compile("(\\w+) *= *('.*'|\".*\"|\\d+|\\w+)");
		Matcher matcher = pattern.matcher(expr);
		while (matcher.find()) {
			setAttribute(matcher.group(1), matcher.group(2));
		}
	}

	public boolean build(String expr) {
		clear();

		setName(expr);

		String regex = "\\@Value\\((.*)\\)";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(expr);
		if (matcher.matches()) {
			buildAttribute(matcher.group(1));
		}

		comparer = new DefaultComparer();

		if (null == valuer) {
			return false;
		}

		return true;
	}

	@Override
	public boolean check(Object object) {
		if (null == comparer || null == valuer) {
			return false;
		}

		return comparer.compare(object);
	}
}
